package tjs.study.mini.springbootstartsmini.boot;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.util.ClassUtils;

/**
 * @author nicky
 * @date 2021/9/8 上午11:57
 */
public class SpringApplication {

    private static final String[] SERVLET_INDICATOR_CLASSES = {"javax.servlet.Servlet",
            "org.springframework.web.context.ConfigurableWebApplicationContext"};

    private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

    private Class<?> primarySource;

    public SpringApplication(Class<?> primarySource) {
        this.primarySource = primarySource;
    }

    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return new SpringApplication(primarySource).run(args);
    }

    public ConfigurableApplicationContext run(String... args) {
        GenericApplicationContext context = createApplicationContext();
        // 注册启动类
        prepareContext(context);
        context.refresh();
        return context;
    }

    private void prepareContext(GenericApplicationContext context) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.primarySource);
        BeanDefinition beanDefinition = builder.getBeanDefinition();
        String beanName = beanNameGenerator.generateBeanName(beanDefinition, context);
        context.registerBeanDefinition(beanName, beanDefinition);
    }


    protected GenericApplicationContext createApplicationContext() {
        for (String className : SERVLET_INDICATOR_CLASSES) {
            if (!ClassUtils.isPresent(className, null)) {
                System.out.println("不存在web相关的class,开始启动非web应用...");
                return new AnnotationConfigApplicationContext();
            }
        }
        System.out.println("存在web相关的class,开始启动web应用...");
        return new AnnotationConfigServletWebServerApplicationContext();
    }
}
